
#include <stdlib.h>

#define nil 		NULL
#define SPECIALS 	" \t\n\v\r();#"
#define MAX_TOK 	128

#ifndef strtof 
float strtof (const char*, char**);
#endif

enum {
	TInt	= 0,
	TFloat,
    TBool,
	TSymbol,
    TLambda,
	TPrimitive,
	TList
};

typedef struct Obj 	    Obj;
typedef struct Cons	    Cons;
typedef struct Prim	    Prim;
typedef struct Lambda   Lambda;

struct Obj
{
	int		t;
	union {
		void	*p;
		long	 l;
		float	 f;
	} u;
};

struct Cons 
{
	Obj	*a;
	Obj	*b;
};

struct Prim
{
	int 	na;
	int		evArgs;
	Obj		*(*f)();
};

struct Lambda
{
    int     nc;
    int     na;
    Obj     *o[1];
};

Obj		*newObj			();
Obj		*mkInt			(long);
Obj		*mkFloat		(float);
Obj		*mkSymbol		(char*);
Obj		*mkPrimitive	(Obj*(*)(), int, int);

int     isFalse         (Obj*);
int     isTrue          (Obj*);

int		 len			(Obj*);
int		 eqStr			(char*, char*);
Obj		**listToArray	(Obj*, int*);

Obj		*parse			();
Obj		*eval 			(Obj*);

Obj		*cons			(Obj*,Obj*);
Obj		*car			(Obj*);
Obj		*cdr			(Obj*);
Obj     *null           (Obj*);
Obj     *atom           (Obj*);
Obj     *eq             (Obj*, Obj*);
Obj     *cond           (int, Obj**);
Obj     *begin          (int, Obj**);
Obj     *lambda         (int, Obj**);
Obj     *applyLambda    (Lambda*, int, Obj**);
Obj     *def            (Obj*, Obj*);

void    addSym          (char*, Obj*);
void    push            (char*, Obj*);
void    popN            (int);
void    pop             ();
Obj     *lookup         (char*);

extern Obj	*pCons,
	   		*pCar,
			*pCdr,
            *pT,
            *pF,
            *pBegin,
            *pCond,
            *pLambda,
            *pNull,
            *pAtom,
            *pEq,
            *pDef,
            *Elist;

